package cc.shacocloud.luanniao.web.service

import cc.shacocloud.luanniao.core.model.po.UserPo
import cc.shacocloud.luanniao.core.exception.UnauthorizedException
import cc.shacocloud.luanniao.core.model.constant.UserAuthRoleEnum
import cc.shacocloud.luanniao.web.model.mo.SessionMo
import cc.shacocloud.luanniao.web.model.mo.UserSessionMo
import org.springframework.http.server.reactive.ServerHttpResponse
import org.springframework.web.reactive.socket.WebSocketSession
import org.springframework.web.server.ServerWebExchange
import kotlin.time.Duration.Companion.hours

/**
 *  会话服务
 * @author 思追(shaco)
 */
interface SessionService {

    companion object {

        /**
         * session 名称
         */
        const val SESSION_NAME = "luanniao-session"

        /**
         * 在查询参数中的session名称
         */
        const val SESSION_NAME_BY_QUERY_PARAM = "_sid"
    }

    /**
     * 保存会话信息
     * @param sessionMo 用户会话信息
     * @param ttl 会话过期事件
     */
    suspend fun saveSession(
        response: ServerHttpResponse,
        sessionMo: SessionMo,
        ttl: kotlin.time.Duration = 12.hours,
    )

    /**
     * 移除会话
     */
    suspend fun removeSession(
        response: ServerHttpResponse,
        sessionMo: SessionMo,
    )

    /**
     * 获取当前访问用户的会话信息
     */
    suspend fun currentSession(exchange: ServerWebExchange): SessionMo

    /**
     * 获取当前访问用户的会话信息
     */
    suspend fun currentSession(session: WebSocketSession): SessionMo

    /**
     * 获取当前会话，如果没有会话则抛出未登录异常
     */
    suspend fun getUserSession(exchange: ServerWebExchange): UserSessionMo {
        val currentSession = currentSession(exchange)
        if (currentSession.role == UserAuthRoleEnum.NOT_LOGGED_USER) {
            throw UnauthorizedException()
        }
        return currentSession as UserSessionMo
    }

    /**
     * 获取当前用户信息
     */
    suspend fun getCurrentUser(exchange: ServerWebExchange): UserPo

    /**
     * 获取当前用户id
     */
    suspend fun getCurrentUserId(exchange: ServerWebExchange): Long

}